package extraction;

import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
/////////////TESTS/////////////////////////
//Si "/" sur la premiere valeur
///////////////////////////////////////////

//Le calcul des maxima ne fonctionne qu avec des nombres (">", "<" et lettres proscrits)
//Seul le "/" est pris en compte en cas de valeurs manquantes
public class Maxima {
	//
	public Maxima(ArrayList<String> dataName){
		dataNameDtb.addAll(dataName);
	}
	
	//Ajout d un parametre sur lequel on calcul le min et le max
	//Prise en compte des heures de reinitialisation
	public void add(String name, Date lastValidDate, Database dtb, int resetMinHour, int resetMaxHour){
		
		//
		names.add(name);
		resetMin.add(resetMinHour);
		resetMax.add(resetMaxHour);
		
		//
		GregorianCalendar gcLast = new GregorianCalendar();
		gcLast.setTime(lastValidDate);
		GregorianCalendar gcMax = new GregorianCalendar();
		gcMax.setTime(lastValidDate);
		GregorianCalendar gcMin = new GregorianCalendar();
		gcMin.setTime(lastValidDate);
		
		//
		if(gcLast.get(GregorianCalendar.HOUR_OF_DAY) < resetMaxHour){
			gcMax.set(GregorianCalendar.DAY_OF_MONTH, gcLast.get(GregorianCalendar.DAY_OF_MONTH) - 1);
		}
		gcMax.set(GregorianCalendar.HOUR_OF_DAY, resetMaxHour);
		gcMax.set(GregorianCalendar.MINUTE, 0);
		
		//
		if(gcLast.get(GregorianCalendar.HOUR_OF_DAY) < resetMinHour){
			gcMin.set(GregorianCalendar.DAY_OF_MONTH, gcLast.get(GregorianCalendar.DAY_OF_MONTH) - 1);
		}
		gcMin.set(GregorianCalendar.HOUR_OF_DAY, resetMinHour);
		gcMin.set(GregorianCalendar.MINUTE, 0);
		
		//
		min.add(dtb.getObs(gcMin.getTime()).getValue(dataNameDtb.indexOf(name)));
		while(dtb.hasDateExist(gcMin.getTime())){
			String valueObs = dtb.getObs(gcMin.getTime()).getValue(dataNameDtb.indexOf(names.get(min.size() - 1)));
			if(!valueObs.matches("/.*") && Double.parseDouble(valueObs) < Double.parseDouble(min.get(min.size() - 1))){
				min.set(min.size() - 1, valueObs);
			}
			gcMin.add(GregorianCalendar.MINUTE, 1);
		}
		
		//
		max.add(dtb.getObs(gcMax.getTime()).getValue(dataNameDtb.indexOf(name)));
		while(dtb.hasDateExist(gcMax.getTime())){
			String valueObs = dtb.getObs(gcMax.getTime()).getValue(dataNameDtb.indexOf(names.get(min.size() - 1)));
			if(!valueObs.matches("/.*") && Double.parseDouble(valueObs) > Double.parseDouble(max.get(max.size() - 1))){
				max.set(max.size() - 1, valueObs);
			}
			gcMax.add(GregorianCalendar.MINUTE, 1);
		}
	}

	//Comparaison a la ou les dernieres obs
	//Reinitialisation a l heure definie
	public void refresh(Obs obs, Date date){
		GregorianCalendar gc = new GregorianCalendar();
		gc.setTime(date);
		
		for(int i = 0; i < names.size(); i++){
			String valueObs = obs.getValue(dataNameDtb.indexOf(names.get(i)));
			resetMin.get(i);
			if(gc.get(GregorianCalendar.HOUR_OF_DAY) == resetMin.get(i) && gc.get(GregorianCalendar.MINUTE) == 0){
				min.set(i, valueObs);
			} else if(!valueObs.matches("/.*") && Double.parseDouble(valueObs) < Double.parseDouble(min.get(i))){
				min.set(i, valueObs);
			}
			if(gc.get(GregorianCalendar.HOUR_OF_DAY) == resetMax.get(i) && gc.get(GregorianCalendar.MINUTE) == 0){
				max.set(i, valueObs);
			} else if (!valueObs.matches("/.*") && Double.parseDouble(valueObs) > Double.parseDouble(max.get(i))){
				max.set(i, valueObs);
			}
		}
	}
	
	//Getter de minima
	public String getMin(String name){
		return min.get(names.indexOf(name));
	}
	
	//Getter de maxima
	public String getMax(String name){
		return max.get(names.indexOf(name));
	}

	private ArrayList<Integer> resetMax = new ArrayList<Integer>();
	private ArrayList<Integer> resetMin = new ArrayList<Integer>();
	private ArrayList<String> dataNameDtb = new ArrayList<String>();
	private ArrayList<String> max = new ArrayList<String>();
	private ArrayList<String> min = new ArrayList<String>();
	private ArrayList<String> names = new ArrayList<String>();
}
